#include "Gscsd.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "FreeRTOS.h"
#include "task.h"

//////////////////////////////////////////////////////////////////
//加入以下代码,支持printf函数,而不需要选择use MicroLIB	  
#if 1
#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE 
{ 
	int handle; 
}; 

FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x) 
{ 
	x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{ 	
	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
	USART1->DR = (u8) ch;      
	return ch;
}
#endif
 
extern void vPortSetupTimerInterrupt( void );
static char dispBuf[128];
/**
 * 使用给定的格式和可变参数列表格式化字符串。
 *
 * @param format 格式化字符串。
 * @param ... 可变参数列表。
 * @return 格式化后的字符串。
 */
char * formatString(const char* format, ...) {
    va_list args;
    va_start(args, format);

    // 使用vsnprintf首先获取格式化后的字符串长度
    int length = vsnprintf(NULL, 0, format, args);
    va_end(args);

    // 再次调用vsnprintf来格式化字符串并保存到分配的内存中
    va_start(args, format);
    vsnprintf(dispBuf, length + 1, format, args);
    va_end(args);

    return dispBuf;
}


/**
 * 在指定范围内以特定步长调整当前值，支持循环。
 *
 * @param currentValue 当前值
 * @param increment 增量，可以是正数或负数
 * @param minValue 范围的最小值（包含）
 * @param maxValue 范围的最大值（包含）
 * @return 新的值，保证在minValue到maxValue之间循环
 */
int AdjustValueWithinRange(int currentValue, int increment, int minValue, int maxValue) {   //4  3    10-3+1
    int rangeSize = maxValue - minValue + 1; // 范围内可能的值的总数
    //先将当前值调整到以0为基础的范围，然后应用增量和循环逻辑，最后再调整回原始范围的基础
    int adjustedValue = (((currentValue - minValue + increment) % rangeSize) + rangeSize) % rangeSize + minValue;
    return adjustedValue;
}
void UsartPrintf(USART_TypeDef *huart,const char* format, ...) {
   
    va_list args;
    va_start(args, format);
	  int i = 0;

    // 使用vsnprintf首先获取格式化后的字符串长度
    int length = vsnprintf(NULL, 0, format, args);
    va_end(args);

    // 再次调用vsnprintf来格式化字符串并保存到分配的内存中
    va_start(args, format);
    vsnprintf(dispBuf, length + 1, format, args);
    va_end(args);
	 
	  while(length--){
		
			USART_SendData(huart,dispBuf[i]);
				/* 等待发送数据寄存器为空 */
    	while (USART_GetFlagStatus(huart, USART_FLAG_TXE) == RESET);	
			i++;
		} 
}      





/*
	操作步骤：
a.根据延时时间和定时器所选时钟频率，计算出定时器要计数的时间数值；
b.获取当前数值寄存器的数值；
c.以当前数值为基准开始计数；
d.当所计数值等于（大于）需要延时的时间数值时退出。
注：计数时间值的计算，我们以延时10us，时钟频率为72MHZ的STM32F103C8T6来计算，
        计数值 = 延时时间/1S × 时钟频率 = 0.000 01/1 *72 000 000 =  720

*/
/**
 * 微秒级延时函数
 *
 * @param us 延时的微秒数
 */
// 定义一个函数，参数为需要延迟的微秒数
void delay_us(__IO uint32_t delay)
{ 
    u32 ticks;
       u32 told,tnow,reload,tcnt=0;
       if((0x0001&(SysTick->CTRL)) ==0)    //定时器未工作
              vPortSetupTimerInterrupt();  //初始化定时器
 
       reload = SysTick->LOAD;                     //获取重装载寄存器值
       ticks = delay * (SystemCoreClock / 1000000);  //计数时间值
       
       vTaskSuspendAll();//阻止OS调度，防止打断us延时
       told=SysTick->VAL;  //获取当前数值寄存器值（开始时数值）
       while(1)
       {
              tnow=SysTick->VAL; //获取当前数值寄存器值
              if(tnow!=told)  //当前值不等于开始值说明已在计数
              {         
                     if(tnow<told)  //当前值小于开始数值，说明未计到0
                          tcnt+=told-tnow; //计数值=开始值-当前值
 
                     else     //当前值大于开始数值，说明已计到0并重新计数
                            tcnt+=reload-tnow+told;   //计数值=重装载值-当前值+开始值  （
                                                      //已从开始值计到0） 
 
                     told=tnow;   //更新开始值
                     if(tcnt>=ticks)break;  //时间超过/等于要延迟的时间,则退出.
              } 
       }  
       xTaskResumeAll();	//恢复OS调度

}
/**
 * 毫秒级延时函数
 *
 * @param ms 延时的毫秒数
 */
void delay_ms(__IO uint32_t ms)
{ 
	for(uint32_t i=0;i<ms;i++){
		delay_us(1000);
	}
}


